﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using System.Drawing;

namespace DX1
{
    class MyTorus : MyObject
    {
                //constructor
        public MyTorus(ref Device d)
            : base(ref d)
        {
        }

        public float innerRadious;

        public Vector3 Spherical(float r, float theta, float phi)
        {
            Vector3 pt = new Vector3();
            float snt = (float)Math.Sin(theta * Math.PI / 180);
            float cnt = (float)Math.Cos(theta * Math.PI / 180);
            float snp = (float)Math.Sin(phi * Math.PI / 180);
            float cnp = (float)Math.Cos(phi * Math.PI / 180);
            
            pt.X = r * snt * cnp;
            pt.Y = r * cnt;
            pt.Z = -r * snt * snp;
            
            return pt;
        }

        public void CreateMyTorus(float outerRadious, float innerRadious)
        {
            int N = 100;
            NoV = N * N;
            int NoF = (NoV) * 6;
            float tessellationStep = 360.0f / N; //(float)Math.Ceiling(Math.PI / N);
            float twoPi = (float)(2*Math.PI);

            vertices = new CustomVertex.PositionNormalTextured[NoV];

            this.radius = outerRadious;
            this.innerRadious = innerRadious;

            #region vertices

            int step = 0;

            for (float t = 0; t < twoPi; t += DegreeToRadian(tessellationStep))
            {
                for (float u = 0; u < twoPi; u += DegreeToRadian(tessellationStep))
                {
                    vertices[step].X = (float)Math.Cos(t) * (outerRadious + innerRadious * (float)Math.Cos(u));
                    vertices[step].Y = (float)Math.Sin(t) * (outerRadious + innerRadious * (float)Math.Cos(u));
                    vertices[step].Z = innerRadious * (float)Math.Sin(u);
                    step++;
                }
            }

            #endregion

            #region indices
            int[] indices = new int[NoF];
            int x = 0;
            for (int i = 0; i < N * N; i++)
            {
                //for (int j = 1; j < N; j++)
                {
                    //int x = 6 * ((N) * (i - 1) + (j - 1));
                    if (i < N * N - N)
                    {
                        indices[x] = i;
                        indices[x + 1] = i + N;
                        indices[x + 2] = i + N + 1;

                        indices[x + 3] = i;
                        indices[x + 4] = i + N + 1;
                        indices[x + 5] = i + 1;

                        if ((i + 1) % N == 0)
                        {
                            indices[x + 2] = i + 1;
                            indices[x + 4] = i + 1;
                            indices[x + 5] = i - N + 1;
                        }
                    }
                    else
                    {
                        indices[x] = i;
                        indices[x + 1] = i - N * N + N;
                        indices[x + 2] = i - N * N + N + 1;

                        indices[x + 3] = i;
                        indices[x + 4] = i - N * N + N + 1;
                        indices[x + 5] = i + 1;

                        if ((i + 1) % N == 0)
                        {
                            indices[x + 2] = i - N * N + 1;
                            indices[x + 4] = i - N * N + 1;
                            indices[x + 5] = i - N + 1;
                        }
                    }
                    x += 6;
                }
            }
            #endregion

            #region texture

            for (int i = 0; i < NoV; i++)
            {
                vertices[i].Tv = (float)Math.Asin(vertices[i].Z / innerRadious) / twoPi;
                vertices[i].Tu = (float)Math.Acos(vertices[i].X / (outerRadious + innerRadious * Math.Cos(vertices[i].Tv * twoPi))) / twoPi;
            }

            #endregion

            m = new Mesh(NoF, NoV, MeshFlags.Managed | MeshFlags.Use32Bit, CustomVertex.PositionNormalTextured.Format, dev);

            m.IndexBuffer.SetData(indices, 0, LockFlags.None);
            m.VertexBuffer.SetData(vertices, 0, LockFlags.None);

            m.ComputeNormals();
            CalculateBounds();
            ExtendedMaterials = new ExtendedMaterial[1];
            Textures = new Texture[1];
            Materials = new Material[1];
            ExtendedMaterials[0] = new ExtendedMaterial();
            Textures[0] = null;
            Materials[0] = new Material();
            Materials[0].Ambient = Color.White;
            Materials[0].Diffuse = Color.White;
        }
    }
}
